<?php
class YWSAuthentication {
    public static $_session = 'YiiWorkshopSession';
    
    public $auth_message;
    
    function __construct() {
        //$this->_session = 'YiiWorkshopSession';
        $this->auth_message = 'Tài khoản hoặc mật khẩu không đúng!';
        
        // Init the session
        if (!isset($_SESSION[YWSAuthentication::$_session]))
        	$_SESSION[YWSAuthentication::$_session] = null;
    }
    
    public function run() {
        // If no identity returns FALSE for redirection action in Controller
        if (!$this->hasIdentity()) return false;
        else {
            // if has identity
            // Authorize            
        }
    }
    
    public function hasIdentity() {
        if (!isset($_SESSION[YWSAuthentication::$_session])) {
            $_SESSION[YWSAuthentication::$_session] = null;        
            return false;
        }
        elseif ($_SESSION[YWSAuthentication::$_session] == null) return false;
        else
            return true;        
    }
    
    public function authenticate($username, $password) {        
        $db = new PortalUsers();
        $username = trim($username);
        $password = trim($password);
        
        // Set timezone - very important
        date_default_timezone_set('Asia/Ho_Chi_Minh');
        
        // Take Username to find
        $criteria = new CDbCriteria();
        $criteria->condition = "username = '".$username."'";
        $result = PortalUsers::model()->find($criteria);        
                
        // If username does not exist. Return false
        if (!$result) {
            $this->auth_message = 'Tài khoản không tồn tại';
            return false;                
        }
        
        // If username exists, Firstly, check if the user is locked or not
        
        if ($result->is_locked == 1) {
            // If locked, check for the last_locked_out date
            $now = strtotime(date('Y-m-d H:i:s'));
            $last_locked = strtotime($result->last_locked_date);            
            $difference = round($now - $last_locked) / 60;                
            // If last locked out date is still in range of 15 minutes --> Continue to lock --> return FALSE
            if ($difference <= 15) {
                $this->auth_message = 'Tài khoản này vẫn đang bị khóa trong 15 phút kể từ :'.$result->last_locked_date;
                return false;
            }
            else {                
                // If out of 15 minutes
                // Reset fail password attempt to 0. unlock user
                $result->is_locked = 0;
                $result->fail_password_attempt_count = 0;
                $result->update();
                // Continue to check for password
                // If password match. return TRUE
                if ($result->password == md5(trim($password))) {                      
                    return $result;
                }
                else {
                    // If password not match. Increase fail attempt by 1. Return FALSE
                    $result->fail_password_attempt_count++;
                    $result->update();
                    
                    $this->auth_message = 'Mật khẩu không chính xác. Lần '.$result->fail_password_attempt_count;
                    return false;
                }                
            }
        }
        else {
            // If user is not locked. Check the failed attempt count            
            $fail = $result->fail_password_attempt_count;
            // If password does not match
            if (strcmp(trim($result->password), trim($password)) != 0) {                
                // Check for fail attempt
                // If it reaches 5 times --> lock account. Reset fail attempt to 0. RETURN FALSE
                // Set last lock date to current
                if ($fail >= 5) {
                    $result->is_locked = 1;
                    $result->fail_password_attempt_count = 0;
                    $result->last_locked_date = date('Y-m-d H:i:s');
                    $result->update(); 
                    
                    $this->auth_message = 'Mật khẩu không chính xác. Lần '.
                            $result->fail_password_attempt_count.
                            '. Tài khoản của bạn sẽ bị khóa 15 phút.';
                }
                else { // Incease fail attempt by 1 
                    $result->fail_password_attempt_count++;
                    $result->update();
                    $this->auth_message = 'Mật khẩu không chính xác. Lần '.$result->fail_password_attempt_count;
                }
                
                return false;
            }
            else {                        
                // If password match. Reset fail attempt to 0. Return TRUE                
                // Reset fail attempt
                $result->fail_password_attempt_count = 0;
                $result->update();

                return $result;          
            }
        }        
    }
    
    public function saveIdentity($userinfo) {        
        // Assign Session array
        $_SESSION[YWSAuthentication::$_session]['account'] = $userinfo->username;
        $_SESSION[YWSAuthentication::$_session]['id'] = $userinfo->id;
        // Check if user is SUPER OR NOT
        if ($userinfo->is_super) $_SESSION[YWSAuthentication::$_session]['roles'] = array('SuperAdministrator');
        else {
            // If not super user then get all the roles
            $_SESSION[YWSAuthentication::$_session]['roles'] = $this->getRoles($userinfo->id);
        }
    }
    
    public function getRoles($user_id) {
        $result = array();
        $db = new PortalUsersInRoles();
        $roles = $db->find('user_id = :user_id', array(':user_id'=>$user_id));
        for ($i = 0; $i < count($roles); $i++) {
            // Each role_id, get role name and add to array $result
            $tmp = new PortalRoles();
            $tmprole = $tmp->find('id = :id', array(':id'=>$role[$i]->role_id));
            $result[] = $tmprole->name;
        }
        return $result;
    }
    
    public static function getIdentityName() {
        if ($_SESSION[YWSAuthentication::$_session] != null)
            return $_SESSION[YWSAuthentication::$_session]['account'];
        else return false;
    }
    
    public static function logOut() {
        $_SESSION[YWSAuthentication::$_session] = null;        
    }
}
?>
